import '../lib/oss_dart.dart';
import 'dart:typed_data';

void main() async {
  print('=== OSS Dart V2 示例 ===');

  // 方式1: 使用STS认证（推荐生产环境）
  OssClient stsClient = OssClient.sts(
    bucketName: 'your-bucket-name',
    endpoint: 'oss-cn-hangzhou.aliyuncs.com',
    tokenGetter: getStsAccount,
  );

  // 方式2: 使用直接认证（适合开发测试）
  OssClient directClient = OssClient.direct(
    bucketName: 'your-bucket-name',
    endpoint: 'oss-cn-hangzhou.aliyuncs.com',
    directAccessKey: 'your-access-key',
    directAccessSecret: 'your-access-secret',
  );

  // 方式3: 使用传统构造函数（向后兼容）
  OssClient legacyClient = OssClient(
    bucketName: 'your-bucket-name',
    endpoint: 'oss-cn-hangzhou.aliyuncs.com',
    tokenGetter: getStsAccount,
  );

  // 选择一个客户端进行演示
  OssClient client = stsClient;

  // 示例文件数据
  List<int> fileData = Uint8List.fromList('Hello OSS World!'.codeUnits);

  String fileKey = 'example/test.txt'; // 上传文件名

  try {
    // 1. 检查文件是否存在（新功能）
    print('1. 检查文件是否存在...');
    bool exists = await client.objectExists(fileKey);
    print('文件是否存在: $exists');

    // 2. 上传文件（内存数据）
    print('2. 开始上传文件...');
    var response = await client.putObject(fileData, fileKey);
    print('上传响应状态码: ${response.statusCode}');

    // 3. 再次检查文件是否存在
    print('3. 上传后检查文件是否存在...');
    exists = await client.objectExists(fileKey);
    print('文件是否存在: $exists');

    // 4. 获取文件元数据（新功能）
    if (exists) {
      print('4. 获取文件元数据...');
      var metaResponse = await client.getObjectMeta(fileKey);
      print('元数据响应状态码: ${metaResponse.statusCode}');
      print('文件大小: ${metaResponse.headers['content-length']} bytes');
      print('文件类型: ${metaResponse.headers['content-type']}');
      print('最后修改时间: ${metaResponse.headers['last-modified']}');
    }

    // 5. 上传本地文件（V2新功能，仅直接认证模式支持）
    if (client.directAccessKey != null) {
      print('5. 上传本地文件...');
      // var uploadResponse = await client.uploadFile('/path/to/local/file.txt', 'remote/file.txt');
      // print('本地文件上传状态码: ${uploadResponse.statusCode}');
    }

    // 6. 下载文件
    print('6. 开始下载文件...');
    response = await client.getObject(fileKey);
    print('下载响应状态码: ${response.statusCode}');
    print('文件内容: ${response.body}');

    // 7. 删除文件（V2新功能，仅直接认证模式支持）
    if (client.directAccessKey != null) {
      print('7. 删除文件...');
      // var deleteResponse = await client.deleteObject(fileKey);
      // print('删除响应状态码: ${deleteResponse.statusCode}');

      // 删除后再次检查文件是否存在
      // exists = await client.objectExists(fileKey);
      // print('删除后文件是否存在: $exists');
    }

    // 5. 分片上传示例（适用于大文件）
    print('5. 开始分片上传...');

    // 第一步：初始化分片上传
    var initResponse = await client.initiateMultipartUpload(fileKey);
    print('初始化分片上传响应状态码: ${initResponse.statusCode}');
    // 从响应中解析uploadId (需要解析XML响应)
    String uploadId = 'your-upload-id'; // 实际使用时需要从initResponse中解析

    // 第二步：上传分片
    num partNum = 1; // 上传分块的序号
    var partResponse = await client.uploadPart(fileData, fileKey, uploadId, partNum);
    String etag = partResponse.headers['etag'] ?? ''; // 获取ETag

    // 第三步：完成分片上传
    List<String> etags = [etag]; // 所有区块上传完成后返回的etag，按顺序排列
    response = await client.completeMultipartUpload(etags, fileKey, uploadId);
    print('分片上传完成，响应状态码: ${response.statusCode}');

    print('=== 所有操作完成 ===');
  } catch (e) {
    print('操作失败: $e');
  }
}

/// 获取阿里云STS临时账号
/// 具体实现参考阿里云STS文档
/// https://help.aliyun.com/document_detail/100624.html
Future<Map<String, dynamic>> getStsAccount() async {
  // 这里应该调用您的后端服务获取STS临时凭证
  // 返回格式如下：
  return {
    'AccessKeyId': 'your-sts-access-key-id',
    'AccessKeySecret': 'your-sts-access-key-secret',
    'SecurityToken': 'your-sts-security-token',
    'Expiration': '2024-12-31T23:59:59Z', // ISO 8601 格式
  };
}
